﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing; 
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BizzUI.UserControls;
using BizzCore;
using BizzCommInterfaces;
using BizzUI.Forms;
using BizzUI.Reports;
using BizzReports;


namespace BizzUI
{
    public partial class BizzCommMainForm : Form
    {

        #region Attributes
        private const string TREEVIEWROOTITLE = "BizzComm Server";
        private const string WORKSPACETITLE = "Área de trabajo";
        private const string CONCRETEINBOXTITLE = "Bandejas de entrada";
        private const string CONCRETEOUTBOXTITLE = "Bandejas de salida";
        private const string RULESTITLE = "Reglas";
        private const string MESSAGEHISTORYTITLE = "Histórico de mensajes";
        private const string CONFIGSECTIONTITLE = "Configuración";
        private const string INBOXTYPETITLE = "Tipos de bandeja de entrada";
        private const string OUTBOXTYPETITLE = "Tipos de bandeja de salida";
        private const string GLOBALCONFIGTITLE = "Configuraciones globales";
        private const string APPLOGTITLE = "Logs de auditoría";
        private const string REPORTSTITLE = "Reportes";
        private RuleControl rulePanel;
        private MainRightPanel _rightPanel;
        private FilterForm filter;
        private string userRole;
        #endregion

        public BizzCommMainForm(string userType)
        {
            InitializeComponent();
            userRole = userType;
            
            initBizzUI();
        }
                
        #region Form extra initialization

        private void initBizzUI()
        {
            try
            {
                BizzSystem s = BizzSystem.getInstance();



                notifyIcon.Icon = global::BizzUI.Properties.Resources.BizzCommServer_downIcon;
                _rightPanel = new MainRightPanel();
                _rightPanel.Dock = DockStyle.Fill;

                splitContainerMain.Panel2.Controls.Add(_rightPanel);
                initMainTreeView();
                //Boton refrescar
                toolStripButtonRefresh.Image = global::BizzUI.Properties.Resources.arrow_refresh_icon;
                toolStripButtonRefresh.Text = "Refrescar";
                toolStripButtonRefresh.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
                toolStripButtonRefresh.Click += new EventHandler(toolStripButtonRefresh_Click);
                //

                //
                //Barra de estado
                toolStripBizzStatus.Text = s.getServerStatus();
                //Boton iniciar procesamiento de reglas
                buttonStartServer.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
                buttonStartServer.Text = "Iniciar proceso";
                buttonStartServer.Click += new EventHandler(itemStartProcess_Click);
                buttonStopServer.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
                buttonStopServer.Click += new EventHandler(itemStopProcess_Click);
                buttonStopServer.Text = "Detener proceso";
                buttonStopServer.Enabled = false;
                //
                //Menu contextual del taskbar
                notifyIcon.BalloonTipTitle = "BizzComm Server";
                notifyIcon.BalloonTipText = "BizzComm Server se ha minimizado";
                notifyIcon.Visible = false;

                notifyIcon.ContextMenuStrip = createMinimizedAppContextMenu();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

        

        private void initMainTreeView()
        {
            //Ver la seguridad aca, si es un admin ve la config, sino no la ve
            ImageList icons = new ImageList();
            icons.ColorDepth = ColorDepth.Depth32Bit;
            icons.Images.Add(global::BizzUI.Properties.Resources.BizzCommServer_downIcon);
            icons.Images.Add(global::BizzUI.Properties.Resources.BizzCommServerStopped);
            icons.Images.Add(global::BizzUI.Properties.Resources.OFOLDER);
            icons.Images.Add(global::BizzUI.Properties.Resources.config);
            icons.Images.Add(global::BizzUI.Properties.Resources.Provider);
            icons.Images.Add(global::BizzUI.Properties.Resources.OPENFOLD);
            icons.Images.Add(global::BizzUI.Properties.Resources.inboxIcon);
            icons.Images.Add(global::BizzUI.Properties.Resources.outboxIcon);
            icons.Images.Add(global::BizzUI.Properties.Resources.AuditLog.ToBitmap());
            icons.Images.Add(global::BizzUI.Properties.Resources.BizzCommServer);
            mainTreeView.ImageList = icons;
            TreeNode root = new TreeNode(TREEVIEWROOTITLE, 0, 0);
            //root.ContextMenuStrip = createMinimizedAppContextMenu();
            
                       
            TreeNode workSpaceNode = new TreeNode(WORKSPACETITLE,2,5);
                        
            TreeNode inBoxesNode = new TreeNode(CONCRETEINBOXTITLE,2,5);
            inBoxesNode.ContextMenuStrip = createInboxContextMenu();
            loadConcreteInboxes(inBoxesNode);

            TreeNode outBoxesNode = new TreeNode(CONCRETEOUTBOXTITLE,2,5);
            outBoxesNode.ContextMenuStrip = createOutboxContextMenu();
            loadConcreteOutboxes(outBoxesNode);
            
            TreeNode rulesNode = new TreeNode(RULESTITLE,2,5);
            
            TreeNode historyNode = new TreeNode(MESSAGEHISTORYTITLE,2,5);
            historyNode.ContextMenuStrip = createHistoryContextMenu();

            TreeNode reportsNode = new TreeNode(REPORTSTITLE, 2, 5);
            loadReports(reportsNode);
            TreeNode configNode = new TreeNode(CONFIGSECTIONTITLE,3,3);
                        
            TreeNode inboxTypesNode = new TreeNode(INBOXTYPETITLE,2,5);
            loadInboxTypes(inboxTypesNode);
            
            TreeNode outBoxTypesNode = new TreeNode(OUTBOXTYPETITLE,2,5);
            loadOutboxTypes(outBoxTypesNode);

            TreeNode globalConfigNode = new TreeNode(GLOBALCONFIGTITLE,2,5);

            TreeNode auditLogsNode = new TreeNode(APPLOGTITLE, 8, 8);
            
            configNode.Nodes.Add(inboxTypesNode);
            configNode.Nodes.Add(outBoxTypesNode);
            configNode.Nodes.Add(globalConfigNode);
            configNode.Nodes.Add(auditLogsNode);

            workSpaceNode.Nodes.Add(inBoxesNode);
            workSpaceNode.Nodes.Add(outBoxesNode);
            workSpaceNode.Nodes.Add(rulesNode);
            workSpaceNode.Nodes.Add(historyNode);
            workSpaceNode.Nodes.Add(reportsNode);

            root.Nodes.Add(workSpaceNode);
            
            if (userRole == "admin") 
                root.Nodes.Add(configNode);


            mainTreeView.Nodes.Add(root);
            root.Expand();
            workSpaceNode.Expand();
            configNode.Expand();


        }

        private void updateRightPanel(TreeNodeCollection nodes)
        {
            
            _rightPanel.initRightPanel(nodes);
        }

        private ContextMenuStrip createMinimizedAppContextMenu()
        {
            ContextMenuStrip contextMenu = new ContextMenuStrip();
            string startServer = "Iniciar procesamiento";
            string stopServer = "Parar procesamiento";
            ToolStripMenuItem itemStartProcess = new ToolStripMenuItem(startServer);
            itemStartProcess.Click += new EventHandler(itemStartProcess_Click);
            itemStartProcess.Image = global::BizzUI.Properties.Resources.start;
            itemStartProcess.Name = startServer;
            ToolStripMenuItem itemStopProcess = new ToolStripMenuItem(stopServer);
            itemStopProcess.Click += new EventHandler(itemStopProcess_Click);
            itemStopProcess.Name = stopServer;
            itemStopProcess.Image = global::BizzUI.Properties.Resources.Stop_icon;
            itemStopProcess.Enabled = false;
            ToolStripMenuItem itemCloseServer = new ToolStripMenuItem("Cerrar servidor");
            
            contextMenu.Items.Add(itemStartProcess);
            contextMenu.Items.Add(itemStopProcess);
            contextMenu.Items.Add(new ToolStripSeparator());
            contextMenu.Items.Add(itemCloseServer);
            return contextMenu;
        }

        private ContextMenuStrip createHistoryContextMenu()
        {
            ContextMenuStrip contextMenu = new ContextMenuStrip();
            ToolStripMenuItem itemFilter = new ToolStripMenuItem("Filtrar");
            itemFilter.Click += new EventHandler(itemFilter_Click);
            contextMenu.Items.Add(itemFilter);
            return contextMenu;
        }

        private void loadReports(TreeNode node)
        {
            ReportsManager rm = ReportsManager.getInstance();
            foreach (IBizzCommand cmd in rm.getBizzCommandList())
            {
                TreeNode[] nodes = node.Nodes.Find(cmd.Title, false);
                if (nodes.Length == 0)
                {
                    TreeNode newNode = new TreeNode(cmd.Title, 2, 5);
                    newNode.Name = cmd.Title;
                    newNode.Tag = cmd;
                    node.Nodes.Add(newNode);
                    
                }
            }
        }

        
        #endregion

        #region Treeview inbox setup

        private void loadInboxTypes(TreeNode node)
        {
            try
            {
                BizzSystem s = BizzSystem.getInstance();
                foreach (IInbox inbox in s.getInboxProviders())
                {
                    TreeNode[] nodes = node.Nodes.Find(inbox.getInboxName(), false);
                    if (nodes.Length == 0)
                    {
                        TreeNode newNode = new TreeNode(inbox.getInboxName(), 4, 4);
                        newNode.Name = inbox.getInboxName();
                        newNode.Tag = inbox;
                        node.Nodes.Add(newNode);
                    }

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(null, ex.Message, null, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            
        }

        private void loadConcreteInboxes(TreeNode node)
        {
            BizzSystem s = BizzSystem.getInstance();
            node.Nodes.Clear();
            foreach (IInbox inbox in s.getConcreteInboxes())
            {
                try
                {
                    string nodeTitle = inbox.getConcreteInboxName() + " (" + inbox.getCount().ToString() + ")";
                    TreeNode[] nodes = node.Nodes.Find(inbox.getConcreteInboxName(), false);
                    if (nodes.Length == 0)
                    {
                        TreeNode newNode = new TreeNode(nodeTitle, 6, 6);

                        newNode.Name = inbox.getConcreteInboxName();
                        newNode.Tag = inbox;
                        newNode.ContextMenuStrip = createInboxNodeContextMenu(newNode);
                        node.Nodes.Add(newNode);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(null, ex.Message, null, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

            }

        }

        private ContextMenuStrip createInboxContextMenu()
        {
            ContextMenuStrip contextMenu = new ContextMenuStrip();
            ToolStripMenuItem itemNewInbox = new ToolStripMenuItem("Nueva bandeja de entrada");
            itemNewInbox.Click += new EventHandler(itemNewInbox_Click);
            contextMenu.Items.Add(itemNewInbox);
            return contextMenu;
        }

        private ContextMenuStrip createInboxNodeContextMenu(TreeNode inboxNode)
        {
            ContextMenuStrip contextMenu = new ContextMenuStrip();
            ToolStripMenuItem itemDeleteInbox = new ToolStripMenuItem("Eliminar bandeja");
            itemDeleteInbox.Click += new EventHandler(itemDeleteInbox_Click);
            itemDeleteInbox.Tag = inboxNode;

            ToolStripMenuItem itemPropertiesInbox = new ToolStripMenuItem("Ver propiedades");
            itemPropertiesInbox.Click += new EventHandler(itemPropertiesInbox_Click);
            itemPropertiesInbox.Tag = inboxNode;

            contextMenu.Items.Add(itemPropertiesInbox);
            contextMenu.Items.Add(itemDeleteInbox);
            return contextMenu;
        }

   

      


        



        #endregion

        #region Treeview outbox setup

        private ContextMenuStrip createOutboxNodeContextMenu(TreeNode outboxNode)
        {
            ContextMenuStrip contextMenu = new ContextMenuStrip();
            ToolStripMenuItem itemDeleteOutbox = new ToolStripMenuItem("Eliminar bandeja");
            itemDeleteOutbox.Click += new EventHandler(itemDeleteOutbox_Click);
            itemDeleteOutbox.Tag = outboxNode;

            ToolStripMenuItem itemPropertiesOutbox = new ToolStripMenuItem("Ver propiedades");
            itemPropertiesOutbox.Click += new EventHandler(itemPropertiesOutbox_Click);
            itemPropertiesOutbox.Tag = outboxNode;

            contextMenu.Items.Add(itemPropertiesOutbox);

            contextMenu.Items.Add(itemDeleteOutbox);
            return contextMenu;
        }

       


        private void loadOutboxTypes(TreeNode node)
        {
            try
            {
                BizzSystem s = BizzSystem.getInstance();
                foreach (IOutbox outbox in s.getOutboxProviders())
                {
                    TreeNode[] nodes = node.Nodes.Find(outbox.getOutboxName(), false);
                    if (nodes.Length == 0)
                    {
                        TreeNode newNode = new TreeNode(outbox.getOutboxName(), 4, 4);
                        newNode.Name = outbox.getOutboxName();
                        newNode.Tag = outbox;
                        node.Nodes.Add(newNode);
                    }
                 
                }
            }
              catch (Exception ex)
            {
                MessageBox.Show(null, ex.Message, null, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }

        private void loadConcreteOutboxes(TreeNode node)
        {
            BizzSystem s = BizzSystem.getInstance();
            node.Nodes.Clear();
            foreach (IOutbox outbox in s.getConcreteOutboxes())
            {
                try
                {
                    string nodeTitle = outbox.getConcreteOutboxName() + " (" + outbox.getCount().ToString() + ")";
                    TreeNode[] nodes = node.Nodes.Find(outbox.getConcreteOutboxName(), false);
                    if (nodes.Length == 0)
                    {
                        TreeNode newNode = new TreeNode(nodeTitle, 7, 7);
                        newNode.Name = outbox.getConcreteOutboxName();
                        newNode.Tag = outbox;
                        newNode.ContextMenuStrip = createOutboxNodeContextMenu(newNode);
                        node.Nodes.Add(newNode);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(null, ex.Message, null, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

            }

        }

        private ContextMenuStrip createOutboxContextMenu()
        {
            ContextMenuStrip contextMenu = new ContextMenuStrip();
            ToolStripMenuItem itemNewOutbox = new ToolStripMenuItem("Nueva bandeja de salida");
            itemNewOutbox.Click += new EventHandler(itemNewOutbox_Click);
            contextMenu.Items.Add(itemNewOutbox);
            return contextMenu;
        }

        

        #endregion
        
        #region Events

        void itemPropertiesOutbox_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem item = (ToolStripMenuItem)sender;
            TreeNode node = (TreeNode)item.Tag;
            IOutbox outbox = ((IOutbox)node.Tag);
            string oldAttributes = outbox.codeMe();
            outbox.getConfigurationWindow();
            BizzSystem s = BizzSystem.getInstance();
            try
            {
                s.dbUpdateConcreteOutbox(oldAttributes, outbox);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }


        void itemPropertiesInbox_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem item = (ToolStripMenuItem)sender;
            TreeNode node = (TreeNode)item.Tag;
            IInbox inbox = ((IInbox)node.Tag);
            string oldAttributes = inbox.codeMe();
            inbox.getConfigurationWindow();
            BizzSystem s = BizzSystem.getInstance();
            try
            {
                s.dbUpdateConcreteInbox(oldAttributes, inbox);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

        void itemDeleteOutbox_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem toolStrip = sender as ToolStripMenuItem;
            TreeNode outboxNode = (TreeNode)toolStrip.Tag;
            IOutbox outbox = (IOutbox)outboxNode.Tag;
            try
            {
                BizzSystem.getInstance().removeConcreteOutbox(outbox);
                loadConcreteOutboxes(outboxNode.Parent);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }


            


        }


        void itemDeleteInbox_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem toolStrip = sender as ToolStripMenuItem;
            TreeNode inboxNode = (TreeNode)toolStrip.Tag;
            IInbox inbox = (IInbox)inboxNode.Tag;
            BizzSystem.getInstance().removeConcreteInbox(inbox);
            loadConcreteInboxes(inboxNode.Parent);
            

        }

        void itemNewOutbox_Click(object sender, EventArgs e)
        {
            ProviderSelection providerSelectionForm = new ProviderSelection("outbox");

            providerSelectionForm.ShowDialog();
        }

        void itemNewInbox_Click(object sender, EventArgs e)
        {
            ProviderSelection providerSelectionForm = new ProviderSelection("inbox");

            providerSelectionForm.ShowDialog();
        }

        private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            Show();
            WindowState = FormWindowState.Normal;
        }

 
        private void mainTreeView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            TreeNode node = mainTreeView.SelectedNode;
            
            buttonStartServer.Visible = false;
            buttonStopServer.Visible = false;
            toolStripSeparatorServer.Visible = false;

            switch (node.Text)
            {
                case APPLOGTITLE:
                    {
                        splitContainerMain.Panel2.Controls.Clear();
                        AuditReport report = new AuditReport();
                        report.Dock = DockStyle.Fill;
                        splitContainerMain.Panel2.Controls.Add(report);
                        break;
                    }
                case RULESTITLE:
                    {
                        showRulesPanel();
                        break;
                    }
                case MESSAGEHISTORYTITLE:
                    {
                        showMessageHistoryPanel(new MessageHistory());
                        break;
                    }
                case TREEVIEWROOTITLE:
                    {
                           buttonStartServer.Visible = true;
                           buttonStopServer.Visible = true;
                           toolStripSeparatorServer.Visible = true;
                           break;
                     
                    }
                case GLOBALCONFIGTITLE:
                    {
                        showConfigPanel();
                        break;
                    }
                default:
                    {
                        if (node.Parent != null && node.Parent.Text == REPORTSTITLE)
                        {
                            showReportPanel((IBizzCommand)node.Tag);
                        }
                        else
                        {
                            splitContainerMain.Panel2.Controls.Clear();
                            splitContainerMain.Panel2.Controls.Add(_rightPanel);
                            updateRightPanel(node.Nodes);
                        }
                        break;
                    }
            }
            

        }
        
        void toolStripButtonRefresh_Click(object sender, EventArgs e)
        {
            TreeNode node = mainTreeView.SelectedNode;
            switch (node.Text)
            {
                case INBOXTYPETITLE: loadInboxTypes(node); break;
                case OUTBOXTYPETITLE: loadOutboxTypes(node); break;
                case CONCRETEINBOXTITLE: loadConcreteInboxes(node); break;
                case CONCRETEOUTBOXTITLE: loadConcreteOutboxes(node); break;
                case RULESTITLE: showRulesPanel(); break;
                case MESSAGEHISTORYTITLE: showMessageHistoryPanel(new MessageHistory()); break;
                case GLOBALCONFIGTITLE: showConfigPanel(); break;


            }
            updateRightPanel(node.Nodes);

        }

        private void BizzCommMainForm_Resize(object sender, EventArgs e)
        {
            if (FormWindowState.Minimized == WindowState)
            {
                notifyIcon.Visible = true;
                notifyIcon.ShowBalloonTip(500);
                Hide();
            }

        }


        void itemStartProcess_Click(object sender, EventArgs e)
        {
            BizzSystem s = BizzSystem.getInstance();
            s.startServer();
            notifyIcon.ContextMenuStrip.Items["Iniciar procesamiento"].Enabled = false;
            notifyIcon.ContextMenuStrip.Items["Parar procesamiento"].Enabled = true;
            buttonStartServer.Enabled = false;
            buttonStopServer.Enabled = true;
            mainTreeView.Nodes[0].ImageIndex = 9;
            mainTreeView.Nodes[0].SelectedImageIndex = 9;
            this.Icon = global::BizzUI.Properties.Resources.BizzCommServer_upIcon;
            notifyIcon.Icon = this.Icon;
            toolStripBizzStatus.Text = s.getServerStatus();
        }

        void itemStopProcess_Click(object sender, EventArgs e)
        {
            BizzSystem s = BizzSystem.getInstance();
            s.stopServer();
            buttonStartServer.Enabled = true;
            buttonStopServer.Enabled = false;
            notifyIcon.ContextMenuStrip.Items["Iniciar procesamiento"].Enabled = true;
            notifyIcon.ContextMenuStrip.Items["Parar procesamiento"].Enabled = false;
            mainTreeView.Nodes[0].ImageIndex = 0;
            mainTreeView.Nodes[0].SelectedImageIndex = 0;
            this.Icon = global::BizzUI.Properties.Resources.BizzCommServer_downIcon;
            notifyIcon.Icon = this.Icon;
            toolStripBizzStatus.Text = s.getServerStatus();
        }

       

        void tsButtonNewRule_Click(object sender, EventArgs e)
        {
            NewRuleForm newRule = new NewRuleForm();
            newRule.ShowDialog();
        }

        void tsButtonDeleteRule_Click(object sender, EventArgs e)
        {
            foreach (BizzCore.Rule theRule in rulePanel.getSelectedRules())
            {
                BizzSystem.getInstance().removeRule(theRule);
            }
        }


        void itemFilter_Click(object sender, EventArgs e)
        {
            if (filter == null) filter = new FilterForm();
            filter.ShowDialog();
            showMessageHistoryPanel(new MessageHistory(filter.getFilterResult()));
            
        }

        private void showRulesPanel()
        {
            splitContainerMain.Panel2.Controls.Clear();
            rulePanel = new RuleControl();
            rulePanel.Dock = DockStyle.Fill;
            splitContainerMain.Panel2.Controls.Add(rulePanel);
            
        }

        private void showMessageHistoryPanel(MessageHistory msgPanel)
        {
            splitContainerMain.Panel2.Controls.Clear();
            //MessageHistory msgPanel = new MessageHistory();
            msgPanel.Dock = DockStyle.Fill;
            splitContainerMain.Panel2.Controls.Add(msgPanel);

        }

        private void showConfigPanel()
        {
            splitContainerMain.Panel2.Controls.Clear();
            GlobalConfigurations globalConfig = new GlobalConfigurations();
            globalConfig.Dock = DockStyle.Fill;
            splitContainerMain.Panel2.Controls.Add(globalConfig);
        }

        private void salirToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Dispose();
        }

        private void showReportPanel(IBizzCommand cmd)
        {
            splitContainerMain.Panel2.Controls.Clear();
            UserControl report = cmd.showReportPanel();
            report.Dock = DockStyle.Fill;
            splitContainerMain.Panel2.Controls.Add(report);
        }
    


        #endregion

        private void acercaDeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show(null, "Diseño de aplicaciones 2 - 2012\n\nFernando Vendramin - Juan Pablo Viscardi", "Acerca de", MessageBoxButtons.OK);
        }

     

       



        


        
    }
}
